Skip to content

ci(triage): label fork PRs and stop auto-closing PRs that only lack an issue link#107

Merged
kevincodex1 merged 5 commits into
mainfrom
fix/pr-triage-fork-token
Jun 27, 2026
Merged

ci(triage): label fork PRs and stop auto-closing PRs that only lack an issue link#107
kevincodex1 merged 5 commits into
mainfrom
fix/pr-triage-fork-token

Conversation

@beardthelion

@beardthelion beardthelion commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

What

The PR triage bot has never labeled a single PR. Both of its target populations fall through:

  • Trusted authors (OWNER/MEMBER/COLLABORATOR) hit the early-return bypass and skip triage entirely.
  • Everyone else opens from a fork, where on: pull_request gives the job a read-only GITHUB_TOKEN regardless of the permissions: block, so addLabels/createComment fail with 403 Resource not accessible by integration.

That second case is the visible one: it's the red Quality-signal triage check on every external contributor's PR (e.g. #103). Because the labels never get applied, the downstream stale→close pipeline (stale.yml keys off needs-issue/needs-description) has also been inert for forks. The advertised flag-then-close flow in CONTRIBUTING.md simply never ran for the contributors it was written for.

Changes

pr-triage.yml: pull_requestpull_request_target. This runs the job in the base-repo context with the declared write token, even for forks. It's safe here specifically because the job never checks out or executes PR head code: it only reads context.payload.pull_request, calls the read-only files API, regex-scans patch strings in actions/github-script, and writes labels/comments. None of the untrusted-code-execution risk that makes pull_request_target dangerous applies. The heavy CI in pr-checks.yml stays on pull_request and keeps its first-time-contributor approval gate.

stale.yml: drop needs-issue from only-pr-labels. Linking an issue is a SHOULD in CONTRIBUTING (required only for protocol-level changes), and plenty of legitimate small PRs have none. Coupling it to the 14/21-day auto-close meant a substantive, well-described PR could be closed purely for missing an issue reference. needs-issue stays as an advisory label and guidance nudge; needs-description (a thin/empty body, a far stronger low-effort signal) remains the sole closer.

Notes

  • pull_request_target reads the workflow from the base branch, so the fix takes effect for fork PRs only once this merges to main. It won't retroactively green an existing failed run.
  • The triage check is not a required status check, so none of this changes merge gating; it removes a spurious red X and makes the labeling/stale pipeline actually function.

Summary by CodeRabbit

  • Bug Fixes
    • Updated the PR triage workflow to run in a safe, read-only context-only mode for fork pull requests.
    • Updated stale/auto-close behavior so only pull requests with the needs-description label are marked stale/closed (missing issue link remains advisory).
  • Chores
    • Refreshed workflow and contribution documentation text to accurately describe the updated “What gets merged, what gets closed” triage and inactivity rules.

…abeled

Fork PRs run the triage job with a read-only GITHUB_TOKEN under the
pull_request event regardless of the workflow's declared write
permissions, so addLabels/createComment fail with 403 'Resource not
accessible by integration' for every external contributor (e.g. #103).

Switch the trigger to pull_request_target, which runs in the base-repo
context with the declared write token. The job never checks out or runs
PR head code (it only reads context.payload and the pulls/files API and
manages labels), so it carries none of the untrusted-code-execution risk
that makes pull_request_target dangerous.
needs-issue flags PRs that link no issue, but linking one is a SHOULD in
CONTRIBUTING (required only for protocol-level changes), and many
legitimate small PRs (docs, obvious fixes) have none. Coupling it to the
14/21-day auto-close was overreach: a substantive, well-described PR
could be closed purely for missing an issue reference.

Keep needs-issue as an advisory label and guidance nudge; leave only
needs-description (an empty/thin body, a far stronger low-effort signal)
as the auto-close trigger.
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ea675a9b-ad35-4b84-9081-93834e9e6bb8

📥 Commits

Reviewing files that changed from the base of the PR and between 5ab628a and 374ef75.

📒 Files selected for processing (1)
  • CONTRIBUTING.md
✅ Files skipped from review due to trivial changes (1)
  • CONTRIBUTING.md

📝 Walkthrough

Walkthrough

The PR updates triage and stale automation to focus on missing descriptions, and rewords contributor guidance to match the same closure rule.

Changes

Workflow configuration updates

Layer / File(s) Summary
Triage trigger update
.github/workflows/pr-triage.yml
The triage workflow changes to pull_request_target, and its inline comments and needs-description guidance text are updated in the same workflow.
Stale label filter
.github/workflows/stale.yml
The stale workflow now targets only needs-description PRs, and the message copy removes needs-issue from the close criteria.
Closure guidance update
CONTRIBUTING.md
The contributing guide rewords the triage and closure rules so the 14-day closure condition applies to missing descriptions, while a missing issue link remains advisory.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Gitlawb/node#58: Updates the same workflow files and the same PR triage / stale-label behavior.

Suggested reviewers

  • kevincodex1

Poem

A bunny hops through YAML streams,
With clearer labels, gentler themes.
Missing descriptions now lead the chase,
While notes stay advisory in their place.
🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the changes well, but it doesn't follow the required template sections or include the checklist/verification fields. Add the template sections: Summary, Motivation & context, Kind of change, What changed, How to verify, and the required checklists.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the two main workflow changes: fork PR triage and stale auto-close behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pr-triage-fork-token

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/stale.yml (1)

29-35: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the stale message to match the narrowed close condition.

Line 29 now targets only needs-description, but Lines 34-35 still mention a missing linked issue, which can mislead contributors about why the PR may close.

Proposed wording fix
           stale-pr-message: >
-            This PR has been inactive for 14 days and is still missing a linked issue
-            or a description. It will be closed in 7 days if there's no update. Push a
+            This PR has been inactive for 14 days and is still missing a description.
+            It will be closed in 7 days if there's no update. Push a
             change or leave a comment to keep it open — no hard feelings, you can reopen
             anytime.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/stale.yml around lines 29 - 35, The stale PR message is
now inconsistent with the narrowed `only-pr-labels: "needs-description"`
condition in the stale workflow. Update the `stale-pr-message` in the stale
workflow configuration so it refers only to the missing description state and
removes any mention of a missing linked issue, keeping the wording aligned with
the `only-pr-labels` and `stale-pr-label` settings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/stale.yml:
- Around line 29-35: The stale PR message is now inconsistent with the narrowed
`only-pr-labels: "needs-description"` condition in the stale workflow. Update
the `stale-pr-message` in the stale workflow configuration so it refers only to
the missing description state and removes any mention of a missing linked issue,
keeping the wording aligned with the `only-pr-labels` and `stale-pr-label`
settings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a1e1d2e7-bf01-49de-a6cd-130c57b19ce6

📥 Commits

Reviewing files that changed from the base of the PR and between abc9ad0 and 8b40407.

📒 Files selected for processing (2)
  • .github/workflows/pr-triage.yml
  • .github/workflows/stale.yml

The auto-close trigger narrowed to needs-description, but the stale
message still told contributors a PR could close for a missing linked
issue. Drop that clause so the warning matches what actually closes a PR.
@beardthelion

beardthelion commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

Fixed in 2f850bb. Dropped the "missing a linked issue" clause from the stale message so it matches the narrowed only-pr-labels: needs-description close condition. Valid catch, thanks.

@beardthelion

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@beardthelion

Copy link
Copy Markdown
Collaborator Author

@kevincodex1 ready when you have a moment. Fixes the triage bot 403-ing on every fork PR (read-only token under pull_request) and narrows the stale auto-close to needs-description only. CI green, no open CodeRabbit threads (its one wording nit on the stale message is fixed in 2f850bb).

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings
[P2] Align the stale filter with the intended close policy
.github/workflows/stale.yml:29
The pinned actions/stale configuration treats only-pr-labels as an all-labels filter, so the previous needs-issue,needs-description value only processed PRs that had both labels, not PRs that only lacked an issue link. Changing this to only needs-description therefore changes the close criteria to every PR missing a description, including PRs that do link an issue, while CONTRIBUTING.md still tells contributors that stale closure applies to PRs with no linked issue or description. Please either update the docs/workflow comments to make the new missing-description-only close policy explicit, or use the action's one-of label filter if the intended policy is the documented OR behavior.

Auto-close is driven by needs-description only; a missing issue link stays
advisory. Align the contributor docs with the workflow so the OR wording no
longer implies a missing issue link can close a PR.
@beardthelion

Copy link
Copy Markdown
Collaborator Author

Good catch. only-pr-labels is an AND filter, so the old needs-issue,needs-description only closed PRs missing both, and the OR wording in CONTRIBUTING.md never quite matched it. Intent here is description-only closure with the issue link staying advisory, so I aligned the docs to that in 374ef75 rather than switching to one-of behavior.

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Findings here

@kevincodex1 LGTM

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kevincodex1 kevincodex1 merged commit 1960f6b into main Jun 27, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants